import { NextResponse } from 'next/server'
import userModule from '@/modules/user'
import bcrypt from "bcryptjs";
import { AUTH_TOKEN, COOKIE_MAX_AGE } from "@/config/settings";
import jwt from '@/utils/jwt'
import roleModule from '@/modules/role';
import isEmail from '@/lib/isemail';

export async function PATCH(request) {
  const codeMap = { 0: '更新成功', 1: '登录验证失败', 2: '用户名不能为空', 3: '用户不存在', 4: '旧密码错误', 5: '服务器错误' };
  const token = request.cookies.get(AUTH_TOKEN)?.value;
  if (!token) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
  try {
    const payload = await jwt.verify(token);
    if (!payload) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
    const { username: payloadUsername } = payload.payload;
    const { username, nickname, avatar, mobile, email, old_password, new_password } = await request.json();
    if (!username) return NextResponse.json({ code: 2, codeMap, message: 'The username cannot be empty' });
    const user = await userModule.get(payloadUsername);
    if (!user) return NextResponse.json({ code: 3, codeMap, message: 'The user does not exist' });
    let password = user.password;
    if (old_password && new_password) {
      const isMatch = await bcrypt.compare(old_password, password);
      if (!isMatch) { return NextResponse.json({ code: 4, codeMap, message: 'The old password is incorrect' }); }
      password = await bcrypt.hash(new_password, 10);
    }

    await userModule.update(user.id, username, password, user.status, nickname, avatar, mobile, email, user.role_id);

    if (username !== payloadUsername) {
      const newToken = await jwt.generate({ ...payload.payload, username });
      const response = NextResponse.json({ code: 0, codeMap, message: 'Success' });
      response.cookies.set(AUTH_TOKEN, newToken, { httpOnly: true, sameSite: 'lax', path: '/', maxAge: COOKIE_MAX_AGE, });
      return response;
    }

    return NextResponse.json({ code: 0, codeMap, message: 'Success' });
  } catch (e) {
    return NextResponse.json({ code: 6, codeMap, message: 'server error' }, { status: 500 });
  }
}

export async function GET(request) {
  const codeMap = { 0: '获取全部用户成功', 1: '用户未找到' }
  const result = await userModule.getAllDetailed();
  if (result.length === 0) return NextResponse.json({ code: 0, codeMap, message: 'No users found' });
  return NextResponse.json({ code: 0, codeMap, message: 'Success', data: result });
}

export async function PUT(request) {
  const codeMap = { 0: '更新成功', 1: '登录验证失败', 2: '用户名不能为空', 3: '用户不存在', 4: '超级管理员只允许有一个账号, 且已注册', 5: '服务器错误' };
  const { id, username, nickname, avatar, mobile, email, password, status, role_id } = await request.json();
  const token = request.cookies.get(AUTH_TOKEN)?.value;
  if (!token) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
  try {
    const payload = await jwt.verify(token);
    if (!payload) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
    if (!username) return NextResponse.json({ code: 2, codeMap, message: 'The username cannot be empty' });
    const role = await roleModule.get(role_id);
    if (role.code === 0) {return NextResponse.json({ code: 4, codeMap, message: 'The super administrator is only allowed to have one account and it must be registered' })};
    const user = await userModule.getById(id);
    if (!user) return NextResponse.json({ code: 3, codeMap, message: 'The user does not exist' });
    if (!!password) { user.password = await bcrypt.hash(password, 10); }
    const res = await userModule.update(id, username, user.password, status, nickname, avatar, mobile, email, role_id);
    if (res.affectedRows === 0) return NextResponse.json({code: 5, codeMap, message: 'server error' }, { status: 500 });
    return NextResponse.json({ code: 0, codeMap, message: 'Success' });
  } catch (e) {
    return NextResponse.json({ code: 5, codeMap, message: 'server error' }, { status: 500 });
  }
}

export async function POST(request) {
  const codeMap = { 0: '添加成功', 1: '登录验证失败', 2: '用户名不能为空', 3: '密码不能为空', 4: '用户已存在', 5: '超级管理员只允许有一个账号, 且已注册', 6: '服务器错误', 7: '邮箱格式不正确'};
  const { username, nickname, avatar, mobile, email, password, status, role_id } = await request.json();
  if (!isEmail(username)) return NextResponse.json({ code: 7, codeMap, message: 'The email format is incorrect' });
  const token = request.cookies.get(AUTH_TOKEN)?.value;
  if (!token) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
  try {
    const payload = await jwt.verify(token);
    if (!payload) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
    if (!username) return NextResponse.json({ code: 2, codeMap, message: 'The username cannot be empty' });
    const user = await userModule.get(username);
    if (user) return NextResponse.json({ code: 3, codeMap, message: 'The user already exists' });
    if (password.trim() === '') return NextResponse.json({ code: 3, codeMap, message: 'The password cannot be empty' });
    const role = await roleModule.get(role_id);
    if (role.code === 0) {return NextResponse.json({ code: 5, codeMap, message: 'The super administrator is only allowed to have one account and it must be registered' })};
    const encryptedPassword = await bcrypt.hash(password, 10);
    const res = await userModule.post(username, encryptedPassword, status || 1, nickname || '', avatar || '', mobile || '', email || '', role_id);
    if (res.affectedRows === 0) return NextResponse.json({code: 6, codeMap, message: 'server error' }, { status: 500 });
    return NextResponse.json({ code: 0, codeMap, message: 'Success' });
  } catch (e) {
    return NextResponse.json({ code: 6, codeMap, message: 'server error' }, { status: 500 });
  }
}

export async function DELETE(request) {
  const codeMap = { 0: '删除成功', 1: '登录验证失败', 2: '删除id不能为空', 3: '传入格式不合法', 4: '用户不存在', 5: '服务器错误', 6: '数据库操作错误' };
  const res = await request.json();
  const token = request.cookies.get(AUTH_TOKEN)?.value;
  if (!token) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
  try {
    const payload = await jwt.verify(token);
    if (!payload) return NextResponse.json({ code: 1, codeMap, message: 'Invalid token' }, { status: 401 });
    if (!res || res?.length === 0) return NextResponse.json({ code: 2, codeMap, message: 'The deleted id cannot be empty' }, { status: 400 });
    if (Array.isArray(res)) {
      res.forEach(async (id) => {
        const user = await userModule.getById(Number(id));
        if (!user) return NextResponse.json({ code: 4, codeMap, message: 'The user does not exist' }, { status: 400 });
      })
      const deleteResult = await userModule.deleteById(res);
      if (deleteResult.affectedRows === 0) return NextResponse.json({code: 6, codeMap, message: 'Database operation error' }, { status: 500 });
    } else if (typeof res === 'string' || typeof res === 'number') {
      const user = await userModule.getById(res);
      if (!user) return NextResponse.json({ code: 4, codeMap, message: 'The user does not exist' }, { status: 400 });
      const deleteResult = await userModule.deleteById(Number(res));
      if (deleteResult.affectedRows === 0) return NextResponse.json({code: 6, codeMap, message: 'Database operation error' }, { status: 500 });
    } else {
      return NextResponse.json({ code: 2, codeMap, message: 'The incoming format is illegal' }, { status: 400 });
    }
    return NextResponse.json({ code: 0, codeMap, message: 'Success' });
  } catch (e) {
    console.log(e)
    return NextResponse.json({ code: 5, codeMap, message: 'Server error' }, { status: 500 });
  }
}